home *** CD-ROM | disk | FTP | other *** search
-
-
- /*
- REMOVEFR.C Function PbRemoverFromGroup: Removers a person entry from
- a group entry.
-
- INPUT: Phonebook structure, and the record id's of the person and group
- entries.
-
- OUTPUT: If successful, removes the person from the group's members list, and
- removes the group from the person's members list. If the change in
- membership affects the group's HardwareType, that field is changed.
- */
-
- #include <stdio.h>
- #include <malloc.h>
- #include <phonebk.h>
-
- int pascal PbRemoveFromGroup(PB *pb, int GroupID, int MemberID)
- {
-
- int i, j, k;
- PBE *group = NULL,
- *person = NULL;
- int retval = FAIL;
- int writ; /* for return from fwrite() */
- LONGWORD offset,
- group_offset,
- person_offset;
- int temperrno = 0; /* for saving Pberrno aside */
- BYTE hasccc = HASCCC; /* for changing a group h/w type */
-
- Pberrno = 0; /* Initially, always reset */
-
- /* First, check params */
- if (pb == NULL) {
- Pberrno = INVALIDPARAMETER;
- return(NULL);
- }
- if ((GroupID < 0) ||
- (GroupID > 999)) {
- Pberrno = INVALIDPARAMETER;
- return(NULL);
- }
- if ((MemberID < 0) ||
- (MemberID > 999)) {
- Pberrno = INVALIDPARAMETER;
- return(NULL);
- }
-
- /* Check that this slight increase of 'free bytes' does not go the limit */
- if ((pb->header.FreeBytes + 2*sizeof(int)) > MAXUNUSEDBYTES) {
- Pberrno = TOOMANYFREEBYTES;
- }
-
- /* Fetch the entries involved */
- if (!(group = PbGetEntry(pb, NULL, NULL, GroupID))) {
- goto getout;
- }
- group_offset = OffsetOfEntry(pb, GroupID);
- if (!(person = PbGetEntry(pb, NULL, NULL, MemberID))) {
- goto getout;
- }
- person_offset = OffsetOfEntry(pb, MemberID);
-
- /* Check that the group IS a group and the person IS a person */
- if (group->type != GROUPENTRY) {
- Pberrno = GROUPCANTBEMEMBER;
- goto getout;
- }
- if (person->type != PERSONENTRY) {
- Pberrno = PERSONCANTHAVEMEMBER;
- goto getout;
- }
-
- /* Check that each IS in the others members list, and set indexes to them */
- for (i=0; i<group->members; i++) {
- if (group->MemberList[i] == MemberID) {
- break;
- }
- }
- if (i == group->members) {
- Pberrno = GROUPDOESNTHAVEMEMBER;
- goto getout;
- }
-
- for (j=0; j<person->members; j++) {
- if (person->MemberList[j] == GroupID) {
- break;
- }
- }
- if (j == person->members) {
- Pberrno = MEMBERDOESNTHAVEGROUP;
- goto getout;
- }
-
- /* Check if this will affect the hardware type of the group */
- if ((group->HardwareType == FAXONLY) && (person->HardwareType == FAXONLY)) {
-
- /* check all members except the current one */
- for (k=0; k<group->members; k++) {
- if (group->MemberList[k] != MemberID) {
- if (HardwareTypeOf(pb, group->MemberList[k], &offset) == FAXONLY) {
- break;
- }
- }
- }
-
- /* If all other members of the group were HASCCC, time to change group */
- if (k == group->members) {
- if (fseek(pb->fp, group_offset + 7L, SEEK_SET)) {
- Pberrno = FSEEKERROR;
- goto getout;
- }
- writ = fwrite(&hasccc, sizeof(BYTE), 1, pb->fp);
- if (writ != 1) {
- Pberrno = CANTWRITE;
- goto getout;
- }
- }
- }
-
- /* ...remove the membership ID's by writes to the fields on the file */
- /* Do this by writing the last member in the list over the one being removed*/
- offset = group_offset + group->length -
- ((group->members - i) * sizeof(int));
- if (fseek(pb->fp, offset, SEEK_SET)) {
- Pberrno = FSEEKERROR;
- goto getout;
- }
- writ = fwrite(&group->MemberList[group->members - 1],
- sizeof(int),
- 1,
- pb->fp);
- if (writ != 1) {
- Pberrno = CANTWRITE;
- goto getout;
- }
-
- /* Now, update the length */
- if (fseek(pb->fp, group_offset + 4L, SEEK_SET)) {
- Pberrno = FSEEKERROR;
- goto getout;
- }
- group->length -= sizeof(int);
- writ = fwrite(&group->length, sizeof(int), 1, pb->fp);
- if (writ != 1) {
- Pberrno = CANTWRITE;
- goto getout;
- }
-
- /* and finally update the members count */
- group->members--;
- if (fseek(pb->fp, group_offset + 2L, SEEK_SET)) {
- Pberrno = FSEEKERROR;
- goto getout;
- }
- writ = fwrite(&group->members, sizeof(int), 1, pb->fp);
- if (writ != 1) {
- Pberrno = CANTWRITE;
- goto getout;
- }
-
- /* Now, for the person entry's fields */
- offset = person_offset + person->length -
- ((person->members - j) * sizeof(int));
-
- if (fseek(pb->fp, offset, SEEK_SET)) {
- Pberrno = FSEEKERROR;
- goto getout;
- }
- writ = fwrite(&person->MemberList[person->members - 1],
- sizeof(int),
- 1,
- pb->fp);
- if (writ != 1) {
- Pberrno = CANTWRITE;
- goto getout;
- }
- /* Now, update the length */
- if (fseek(pb->fp, person_offset + 4L, SEEK_SET)) {
- Pberrno = FSEEKERROR;
- goto getout;
- }
- person->length -= sizeof(int);
- writ = fwrite(&person->length, sizeof(int), 1, pb->fp);
- if (writ != 1) {
- Pberrno = CANTWRITE;
- goto getout;
- }
-
- /* and finally update the members count */
- person->members--;
- if (fseek(pb->fp, person_offset + 2L, SEEK_SET)) {
- Pberrno = FSEEKERROR;
- goto getout;
- }
- writ = fwrite(&person->members, sizeof(int), 1, pb->fp);
- if (writ != 1) {
- Pberrno = CANTWRITE;
- goto getout;
- }
-
- /* Tweak the phonebook's 'free bytes' field */
- if (fseek(pb->fp, 6L, SEEK_SET)) {
- Pberrno = FSEEKERROR;
- goto getout;
- }
- pb->header.FreeBytes += 2 * sizeof(int);
- writ = fwrite(&pb->header.FreeBytes, sizeof(BYTE), 1, pb->fp);
- if (writ != 1) {
- Pberrno = CANTWRITE;
- goto getout;
- }
-
- if (!group->members) { /* last member: remove group */
- if (!(PbRemoveEntry(pb, GroupID))) {
- goto getout;
- }
- }
-
- /* If we got here, all went well! */
- retval = SUCCESS;
-
- getout:
-
- /* first save Pberrno aside because PbFreePBE would reset it */
- if (Pberrno) {
- temperrno = Pberrno;
- }
- if (group) {
- PbFreePBE(pb, group);
- }
- if (person) {
- PbFreePBE(pb, person);
- }
- if (temperrno) {
- Pberrno = temperrno;
- }
- return(retval);
- }